#include "DatumLines.h"
#include "globals.h"
#include <d3dx9.h>
#include <string>
#include "Utility.h"

//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

HRESULT DatumLines::Draw() 
{
	D3DXMATRIXA16 trans;
	D3DXMATRIXA16 rotY;
	D3DXMATRIXA16 rotX;
	D3DXMATRIXA16 movX;
	D3DXMATRIXA16 movY;
	D3DXMATRIXA16 mat;
	D3DXMATRIXA16 matWorld;
	D3DXMATRIXA16 scale;
	const float scaleXY = 0.7f;
	const float scaleZ =  1.3f;
		
	g_engine.getVCard()->SetTexture(0, 0);
	g_engine.getVCard()->SetMaterial(&CUtility::CreateMaterial(0.0f, 0.0f, 0.7f));
	D3DXMatrixScaling(&scale, scaleXY, scaleXY, scaleZ);
	D3DXMatrixTranslation(&trans, 0.0f, 0.0f, -(maxBounds.z - minBounds.z)*1.3f);
	mat = scale * trans;
	g_engine.getVCard()->SetTransform(D3DTS_WORLD, &mat);

	if( FAILED (mesh->DrawSubset(0) ) ) 
		return E_FAIL;

	if( FAILED (mesh->DrawSubset(1) ) ) 
		return E_FAIL;
	
	D3DXMatrixRotationY(&rotY, - D3DX_PI / 2.0f);
	D3DXMatrixTranslation(&movX, (maxBounds.z - minBounds.z)*scaleZ, 0.0f, 0.0f);
	mat = scale * rotY * movX ;
	g_engine.getVCard()->SetTransform(D3DTS_WORLD, &mat);
	g_engine.getVCard()->SetMaterial(&CUtility::CreateMaterial(0.7f, 0.0f, 0.0f));

	if( FAILED (mesh->DrawSubset(0) ) ) 
		return E_FAIL;

	if( FAILED (mesh->DrawSubset(1) ) ) 
		return E_FAIL;

	D3DXMatrixRotationX(&rotX, D3DX_PI / 2.0f);
	D3DXMatrixTranslation(&movY, 0.0f, (maxBounds.z - minBounds.z)*scaleZ, 0.0f);
	mat = scale * rotX * movY ;
	g_engine.getVCard()->SetTransform(D3DTS_WORLD, &mat);
	g_engine.getVCard()->SetMaterial(&CUtility::CreateMaterial(0.0f, 0.7f, 0.0f));

	if( FAILED (mesh->DrawSubset(0) ) ) 
		return E_FAIL;

	if( FAILED (mesh->DrawSubset(1) ) ) 
		return E_FAIL;

/*	g_engine.getVCard()->GetTransform(D3DTS_WORLD, &matWorld);
	//m_pTextSprite->SetTransform(&trans);
	m_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_DEPTH_BACKTOFRONT);
    // Pass in DT_NOCLIP so we don't have to calc the bottom/right of the rect
	RECT rc;
    SetRect( &rc, 150, 200, 0, 0 );
	m_pFont->DrawText( m_pTextSprite, L"This is a trivial call to ID3DXFont::DrawText", -1, &rc, DT_NOCLIP,
                       D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
	m_pTextSprite->End();*/

	return S_OK;
}

HRESULT DatumLines::Init() 
{
	LPD3DXBUFFER materialsBuffer;

	if (FAILED ( D3DXLoadMeshFromX(L"Media\\arrow.x",
		0,
		g_engine.getVCard(),
		NULL,
		&materialsBuffer,
		NULL,
		&numMaterials,
		&mesh) ) )
			return E_FAIL;

	if( FAILED ( storeBoundingBox() ) )
		return E_FAIL;

	if ( FAILED( InitFont() ) )
		return E_FAIL;

	D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)materialsBuffer->GetBufferPointer();

    materials = new D3DMATERIAL9[numMaterials];
	textures = new LPDIRECT3DTEXTURE9[numMaterials];

    for(DWORD i = 0; i < numMaterials; i++)  
    {
		if(tempMaterials[i].pTextureFilename)
		{
			materials[i] = tempMaterials[i].MatD3D;  
			materials[i].Ambient = materials[i].Diffuse; 
			std::string texFilename(tempMaterials[i].pTextureFilename);
			std::string texFilepath("Media\\");
			std::string texFileFullName = texFilepath + texFilename;
		
			if( FAILED( D3DXCreateTextureFromFileA(g_engine.getVCard(),
												 texFileFullName.c_str(),
												 &textures[i]))) 
			{
				textures[i] = NULL; 
				return E_FAIL;
			}
		} else {

			textures[i] = NULL;
			// make a default material in the case where the mesh did not provide one
/*			{
				ZeroMemory(&materials[0], sizeof( D3DMATERIAL9 ) );
				materials[i].Diffuse.r = 0.5f;
				materials[i].Diffuse.g = 0.5f;
				materials[i].Diffuse.b = 0.5f;
				materials[i].Specular = materials[i].Diffuse;
				textures[i]=0;
			}*/
		}
    }
    return S_OK;
}

void DatumLines::Cleanup() 
{
	SAFE_RELEASE(mesh);
}


HRESULT DatumLines::storeBoundingBox()
{
	BYTE* pVertices = NULL;

	HRESULT hr = mesh->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID*)&pVertices);
	if (FAILED(hr))
		   return FALSE;

	D3DXComputeBoundingBox((D3DXVECTOR3*)pVertices, mesh->GetNumVertices(), D3DXGetFVFVertexSize(mesh->GetFVF()), &minBounds, &maxBounds);

	mesh->UnlockVertexBuffer();
}

HRESULT DatumLines::InitFont()
{
    HDC hDC = GetDC( NULL );
    int nLogPixelsY = GetDeviceCaps( hDC, LOGPIXELSY );
    ReleaseDC( NULL, hDC );

    int nHeight = -m_fontSize * nLogPixelsY / 72;
	HRESULT hr = D3DXCreateFont( g_engine.getVCard(),            // D3D device
                         nHeight,               // Height
                         0,                     // Width
                         FW_BOLD,               // Weight
                         1,                     // MipLevels, 0 = autogen mipmaps
                         FALSE,                 // Italic
                         DEFAULT_CHARSET,       // CharSet
                         OUT_DEFAULT_PRECIS,    // OutputPrecision
                         DEFAULT_QUALITY,       // Quality
                         DEFAULT_PITCH | FF_DONTCARE, // PitchAndFamily
                         NULL,              // pFaceName
                         &m_pFont );              // ppFont
    if( FAILED( hr ) )
        return hr;

	if( FAILED( hr = D3DXCreateSprite( g_engine.getVCard(), &m_pTextSprite ) ) )
        return hr;
}
